package hzst.android.form;

import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import hzst.android.R;
import hzst.android.entity.BaseUser;
import hzst.android.form.info.BaseViewInfo;
import hzst.android.form.info.BaseViewInfo.SpecialValue;
import hzst.android.form.info.BaseViewInfo.SubmitValue;
import hzst.android.form.info.EditViewInfo;
import hzst.android.form.info.SelectableViewInfo;
import hzst.android.form.view.FMAccessoryView;
import hzst.android.form.view.FMCheckGroup;
import hzst.android.form.view.FMDateSection;
import hzst.android.form.view.FMDateView;
import hzst.android.form.view.FMFormView;
import hzst.android.form.view.FMEditText;
import hzst.android.form.view.FMSpinner;
import hzst.android.form.view.FMTextView;
import hzst.android.form.view.FMOpinionView;
import hzst.android.form.view.FMSelectView;
import hzst.android.util.FontUtil;
import hzst.android.util.L;
import hzst.android.util.PhoneUtil;
/**
 * 创建表单工具类。
 * @author wt
 *
 */
public class ViewCreator {
	private Context context;
	private List<BaseViewInfo> viewList;//表单中的控件绑定的数据
	private LinearLayout contentView;
	private Map<String, String> parameters;//任务相关数据
	
	private float density;
	
	public ViewCreator(Context context,String json,BaseUser user,LinearLayout contentView) {
		this.context = context;
		this.contentView = contentView;
		PhoneUtil phoneHelper = new PhoneUtil(context);
		density = phoneHelper.getDensity();
		ViewInfoProcessor processor = new ViewInfoProcessor();
		viewList = processor.getViewInfo(json,user);
		parameters = processor.getParameters();
	}
	
	public List<BaseViewInfo> getViewList() {
		return viewList;
	}

	/**
	 * 与{@link BaseViewInfo}中的viewType匹配，动态生成表单中的控件。
	 */
	/**
	 * 任务相关数据{@link #parameters}
	 */
	public static final String VIEW_TYPE_TASK = "TransferParameter";
	/**
	 * 从表数据(控件相关数据保存在从表中)
	 */
	public static final String VIEW_TYPE_TABLE = "Table";
	/*
	 * 控件类型，对应各个控件。
	 */
	/**
	 * {@link FMTextView}
	 */
	public static final String VIEW_TYPE_TV = "TextView";
	/**
	 * {@link FMSpinner}
	 */
	public static final String VIEW_TYPE_SP = "Spinner";
	/**
	 * {@link FMCheckGroup}
	 */
	public static final String VIEW_TYPE_CG = "CheckGroup";
	/**
	 * {@link FMDateView}
	 */
	public static final String VIEW_TYPE_DV = "DateView";
	/**
	 * {@link FMDateSection}
	 */
	public static final String VIEW_TYPE_DS = "DateSection";
	/**
	 * {@link FMEditText}
	 */
	public static final String VIEW_TYPE_ET = "EditText";
	/**
	 * {@link FMAccessoryView}
	 */
	public static final String VIEW_TYPE_AV = "AccessoryView";//附件选择控件
	/**
	 * {@link FMOpinionView}
	 */
	public static final String VIEW_TYPE_OPINION = "OpinionView";//意见控件
	/**
	 * {@link FMSelectView}
	 */
	public static final String VIEW_TYPE_SV = "SelectView";//选择新页面(包括人员、课题等)列表中的一条或多条项目，并回写到文本框
	/**
	 * {@link FMFormView}
	 */
	public static final String VIEW_TYPE_FV = "FormView";//表格控件
	
	/*
	 * 标题和内容的宽度比例
	 */
	public static final int WEIGHT_TITLE = 2;
	public static final int WEIGHT_CONTENT = 3;
	/*
	 * 标题和内容的背景色，表单中的一个单元格分为标题(左)和内容(右)两部分
	 */
	public static final int COLOR_NAME = R.color.bg_form_name;
	public static final int COLOR_CONTENT = R.color.bg_form_content;
	
	public Map<String, String> getParameters() {
		return parameters;
	}
	/**
	 * @param contentView 承载表单的控件
	 * @return
	 */
	public void createViews(List<BaseViewInfo> viewList){
		//设置背景色为边框颜色，用来反衬出边框
		contentView.setBackgroundColor(context.getResources().getColor(R.color.divider_general));
		/*
		 * 设置单元格名称的背景色和比例
		 */
		int titleColor = context.getResources().getColor(COLOR_NAME);
		LinearLayout.LayoutParams paramsTitle = new LinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT);
		paramsTitle.weight = WEIGHT_TITLE;
		/*
		 * 设置单位格的边框
		 */
		LinearLayout.LayoutParams paramsLine = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
		paramsLine.setMargins(0, 0, 0, (int) (0.5*density));
		
		for (int j = 0; j < viewList.size(); j++) {
			BaseViewInfo info = viewList.get(j);

			View view = createViewByType(info,j);
			/*
			 * 为从表类型则不创建
			 */
			if(!VIEW_TYPE_TABLE.equals(info.getViewType())){
				LinearLayout llay = new LinearLayout(context);
				llay.setOrientation(LinearLayout.HORIZONTAL);
				llay.setLayoutParams(paramsLine);
				llay.setMinimumHeight((int) (40*density));

				if(!"".equals(info.getName())){
					TextView tvName = new TextView(context);
					
					tvName.setText(info.getName());
					tvName.setTextSize(18);
					tvName.setTextColor(context.getResources().getColor(R.color.text_gray3));
					tvName.setLayoutParams(paramsTitle);
					tvName.setBackgroundColor(titleColor);
					tvName.setPadding(20, 20, 20, 20);
					tvName.setGravity(Gravity.CENTER_VERTICAL);
					llay.addView(tvName);
				}

				/*
				 * 创建单元格的内容
				 */
				
				llay.addView(view);
				contentView.addView(llay);
				
				/*
				 * 底部留出一点间距
				 */
				if(j == viewList.size() - 1){
					LinearLayout.LayoutParams paramsBottom = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,(int) (density*10));
					View viewBottom = new View(context);
					viewBottom.setLayoutParams(paramsBottom);
					viewBottom.setBackgroundColor(context.getResources().getColor(COLOR_CONTENT));
					contentView.addView(viewBottom);
				}
			}
		}
		
	}
	/**
	 * 
	 * @param info 控件绑定的数据
	 * @param index 控件在表单中的位置
	 * @return
	 */
	private View createViewByType(final BaseViewInfo info,int index){
		View view = null;

		if(VIEW_TYPE_TV.equals(info.getViewType())){
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
			params.gravity = Gravity.CENTER_VERTICAL;
			params.setMargins((int) (5*density), 0, 0, 0);
			view = new FMTextView(context);
			view.setLayoutParams(params);
			((FMTextView)view).setInfo(info, this);
			((FMTextView)view).showView();
			
		}else if(VIEW_TYPE_SP.equals(info.getViewType())){
			view = new FMSpinner(context);
			((FMSpinner)view).setInfo(info, this);
			((FMSpinner)view).showView();
			
		}else if(VIEW_TYPE_CG.equals(info.getViewType())){
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);
			view = new FMCheckGroup(context);
			view.setLayoutParams(params);
			((FMCheckGroup)view).setInfo(info, this);
			((FMCheckGroup)view).showView();
			
		}else if(VIEW_TYPE_DV.equals(info.getViewType())){
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
			params.setMargins((int) (5*density), 0, 0, 0);
			view = new FMDateView(context);
			view.setLayoutParams(params);
			((FMDateView)view).setInfo(info, this);
			((FMDateView)view).showView();
			
		}else if(VIEW_TYPE_DS.equals(info.getViewType())){
			view = new FMDateSection(context);
			((FMDateSection)view).setInfo(info);
			((FMDateSection)view).setReadOnly(info.isReadOnly());
			((FMDateSection)view).showView(this);
			
		}else if(VIEW_TYPE_ET.equals(info.getViewType())){
			view = new FMEditText(context);
			((FMEditText)view).setInfo(info, this);
			((FMEditText)view).showView();
			
		}else if(VIEW_TYPE_AV.equals(info.getViewType())){
			info.setMustFill(false);//附件默认为非必填
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
			view = new FMAccessoryView(context);
			if(info.isReadOnly()){
				((FMAccessoryView)view).setEnable(false);
			}
			view.setLayoutParams(params);
			
		}else if(VIEW_TYPE_OPINION.equals(info.getViewType())){
			view = new FMOpinionView(context);
			((FMOpinionView)view).setInfo(info, this);
			((FMOpinionView)view).showView();
			
		}else if(VIEW_TYPE_SV.equals(info.getViewType())){
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
			view = new FMSelectView(context);
			view.setLayoutParams(params);
			((FMSelectView)view).setInfo(info, this);
			
		}else if(VIEW_TYPE_FV.equals(info.getViewType())){
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
			view = new FMFormView(context);
			view.setLayoutParams(params);
			((FMFormView)view).setInfo(info, this);
			((FMFormView)view).showView();
		}else if(VIEW_TYPE_TABLE.equals(info.getViewType())){
			createViews(viewList.get(index).getSlaveTableInfos());
			return null;
		}
		
		view.setTag(index);
		
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT);
		params.weight = WEIGHT_CONTENT;
		
		LinearLayout llay = new LinearLayout(context);
		llay.setLayoutParams(params);
		llay.setBackgroundColor(context.getResources().getColor(COLOR_CONTENT));
		llay.addView(view);
		
		return llay;
	}
	/**
	 * 根据提交数据的字段名称来保存数据。
	 * @param feild
	 * @param value
	 * @param info
	 */
	public void setSubmitValue(String feild,String value,BaseViewInfo info){
		List<SubmitValue> submitValues = info.getSubmitValues();
		for (int i = 0; i < submitValues.size(); i++) {
			SubmitValue submitValue = submitValues.get(i);
			if(submitValue.getFieldName().equals(feild)){
				submitValue.setValue(value);
				submitValues.set(i, submitValue);
				break;
			}
		}
	}
	
	/**
	 * 控件只有一个提交数据时,可以用该方法来保存数据。
	 * @param value
	 * @param info
	 */
	public void setSubmitValue(String value,BaseViewInfo info){
		List<SubmitValue> submitValues = info.getSubmitValues();
		SubmitValue submitValue = submitValues.get(0);
		submitValue.setValue(value);
		submitValues.set(0, submitValue);
	}
	/**
	 * 根据提交数据的下标(在json中的下标)来保存数据。
	 * @param value
	 * @param info
	 * @param index
	 */
	public void setSubmitValue(String value,BaseViewInfo info,int index){
		List<SubmitValue> submitValues = info.getSubmitValues();
		SubmitValue submitValue = submitValues.get(index);
		submitValue.setValue(value);
		submitValues.set(index, submitValue);
	}
	
	/**
	 * 添加需要上传的特殊事件相关的数据
	 * @param value
	 * @param info
	 */
	public void setSpecialValue(String value,BaseViewInfo info){
		List<SpecialValue> specialValues = info.getSpecialValues();
		SpecialValue specialValue = specialValues.get(0);
		specialValue.setValue(value);
		specialValues.set(0, specialValue);
	}
	
	public void setSpecialValue(String value,BaseViewInfo info,int index){
		List<SpecialValue> specialValues = info.getSpecialValues();
		SpecialValue specialValue = specialValues.get(index);
		specialValue.setValue(value);
		specialValues.set(index, specialValue);
	}
	
	/**
	 * 把需要上传的数据拼成json，
	 * 需要上传的数据有两部分，常规控件的数据；特殊控件的数据(非常规的操作下产生的数据)。
	 * @param viewList
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public String createSubmitData(List<BaseViewInfo> viewList,Map<String, String> parameters){
		StringBuffer sb = new StringBuffer("");
		sb.append("[");
		sb.append("{");
		
		/*
		 * 拼接任务相关数据
		 */
		Set<String> keySet = parameters.keySet();
		Iterator<String> iterator = keySet.iterator();
		while(iterator.hasNext()){
			String key = iterator.next();
			sb.append("\"");
			sb.append(key);
			sb.append("\":\"");
			sb.append(URLEncoder.encode(parameters.get(key)));
			sb.append("\"");
			sb.append(",");
		}

		for (int i = 0; i < viewList.size(); i++) {
			BaseViewInfo info = viewList.get(i);
			//有从表数据时
			if(VIEW_TYPE_TABLE.equals(info.getViewType())){
				if(!(sb.lastIndexOf("]") == sb.length())){
					if(sb.length() > 1){
						sb.setLength(sb.length() - 1);
					}
					sb.append("}");
					sb.append("]");
				}
				sb.append("_$$_");//连接表之间的数据
				String slaveData = createSubmitData(info.getSlaveTableInfos(),info.getParameters());
				sb.append(slaveData);
			}else{
				/*
				 * 非空校验
				 */
				List<SubmitValue> submitValues = info.getSubmitValues();
				if(!(info instanceof SelectableViewInfo)){
					for (int j = 0; j < submitValues.size(); j++) {
						String value = submitValues.get(j).getValue();
						if((value == null || "".equals(value)) && info.isVisible() && info.isMustFill()){
							Toast.makeText(context, info.getName()+"不能为空", Toast.LENGTH_SHORT).show();
							return null;
						}
					}
				}
				/*
				 * 最大字数校验
				 */
				if(info instanceof EditViewInfo){
					String value = submitValues.get(0).getValue();
					if(value != null){
						if(FontUtil.isBeyondTextLimit(value, ((EditViewInfo)info).getMaxEms()) && ((EditViewInfo)info).getMaxEms() > 0){
							Toast.makeText(context, info.getName()+"字数超出限制", Toast.LENGTH_SHORT).show();
							return null;
						}
					}
				}
				/*
				 * 拼接控件数据
				 */
				for (int j = 0; j < submitValues.size(); j++) {
					SubmitValue submitValue = submitValues.get(j);
					String value = submitValue.getValue();
					if(value == null){
						value = "";
					}
					sb.append("\"");
					sb.append(submitValue.getFieldName());
					sb.append("\":\"");
					sb.append(URLEncoder.encode(value));
					sb.append("\"");
					sb.append(",");
				}
				/*
				 * 拼接特殊事件数据
				 */
				List<SpecialValue> specialValues = info.getSpecialValues();
				for (int j = 0; j < specialValues.size(); j++) {
					SpecialValue specialValue = specialValues.get(j);
					String value = specialValue.getValue();
					sb.append("\"");
					sb.append(specialValue.getFieldName());
					sb.append("\":\"");
					sb.append(URLEncoder.encode(value));
					sb.append("\"");
					sb.append(",");
				}
			}
		}
		if(sb.lastIndexOf("]") != sb.length()-1){
			sb.setLength(sb.length() - 1);
			sb.append("}");
			sb.append("]");
		}

		L.showLogInfo(L.TAG_OTHER_INFO, "保存审批："+sb);
		return sb.toString();
	}
	
	
	public interface OnValueChangeListener{
		//控件中的值改变时的回调函数
		void valueChanged(List<BaseViewInfo> viewInfo);
	}

}
